#include "stdio.h"
#include "stdlib.h"
#include "string.h"

#define SPACE            0x20
#define HTAB             0x09
#define DELETE_KEY           0x7F

#define CR               0x0D
#define LF               0x0A

#define SO               0x0E     /* shift out */
#define SI               0x0F     /* shift in */

#define ESC              0x1B

#define CRLF_STR         "\r\n"
#define LWSP_STR         "\t "
#define WS_STR           "\r\n\t "

static char base64EncodeTable[64] = {
	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
	'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
	'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
	'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	'+', '/'
};



typedef enum {
	mimeSuccess,
	mimeMemory,
	mimeTruncated,
	mimeFormat
} SFMIME_ResultType;

char* encode(char* input, char* output, int size);
SFMIME_ResultType SFMIME_encodeBase64(char *src, 
									  size_t srcLen,
									  char *result,
									  size_t resLen, 
									  size_t *resSize,
									  int   lineBreak );

int main(int argc, char* argv[])
{
	char input;
	char output[76];
	printf("input : ");
	scanf("%c", &input);
	size_t res = 1;
	size_t* resSize = &res;
	//char* sfasdfads = encode(input,output, sizeof(input));
	//printf("output : %c", sfasdfads);
	SFMIME_encodeBase64(input, 1, output, strlen(output), resSize, 1);	
	printf("output : %c", output);
	scanf("%c", &output);
	return EXIT_SUCCESS;
}

char* encode(char* input, char* output, int size){
	char temp[76]={0,};

	temp[0] = base64EncodeTable[2<<2];
	memcpy(output, temp, sizeof(char));

	return output;
}

SFMIME_ResultType SFMIME_encodeBase64(
	char *src, size_t srcLen, char *result, size_t resLen, size_t *resSize,
	int   lineBreak
)
{

	int  remain, dest;
	char encodeBuffer[76];

	dest   = 0;
	remain = srcLen;
	while (remain > 0)
	{
		unsigned int bufLen = 0;

		while (remain > 0 && bufLen < 76)
		{
			int srcIdx  = srcLen - remain;
			int quantum = (remain >= 3 ? 3 : remain);

			unsigned char n1, n2, n3;

			if (quantum == 3)
			{
				n1 = (unsigned char) src[srcIdx];
				n2 = (unsigned char) src[srcIdx + 1];
				n3 = (unsigned char) src[srcIdx + 2];

				encodeBuffer[bufLen] =
					base64EncodeTable[n1 >> 2];
				encodeBuffer[bufLen + 1] =
					base64EncodeTable[((n1 & 0x03) << 4) | (n2 >> 4)];
				encodeBuffer[bufLen + 2] =
					base64EncodeTable[((n2 & 0x0F) << 2) | (n3 >> 6)];
				encodeBuffer[bufLen + 3] =
					base64EncodeTable[n3 & 0x3F];
			} else if (quantum == 2)
			{
				n1 = (unsigned char) src[srcIdx];
				n2 = (unsigned char) src[srcIdx + 1];

				encodeBuffer[bufLen] =
					base64EncodeTable[n1 >> 2];
				encodeBuffer[bufLen + 1] =
					base64EncodeTable[((n1 & 0x03) << 4) | (n2 >> 4)];
				encodeBuffer[bufLen + 2] =
					base64EncodeTable[(n2 & 0x0F) << 2];
				encodeBuffer[bufLen + 3] = '=';
			} else {  /* quantum == 1 */
				n1 = (unsigned char) src[srcIdx];

				encodeBuffer[bufLen] =
					base64EncodeTable[n1 >> 2];
				encodeBuffer[bufLen + 1] =
					base64EncodeTable[(n1 & 0x03) << 4];
				encodeBuffer[bufLen + 2] = '=';
				encodeBuffer[bufLen + 3] = '=';
			}

			remain -= quantum;
			bufLen += 4;
		}

		if (bufLen < (resLen - dest))
		{
			memcpy(result+dest, encodeBuffer, bufLen);

			if (lineBreak)
			{
/*				result[dest+bufLen] = LF;
				dest += bufLen + 1;
*/
				result[dest+bufLen] = CR;
				result[dest+bufLen+1] = LF;
				dest += bufLen + 2;
			} else {
				dest += bufLen;
			}
		} else {
			memcpy(result+dest, encodeBuffer, (resLen - dest));

			*resSize = resLen;
			if (bufLen == (resLen - dest) && remain == 0)
				return mimeSuccess;
			else
				return mimeTruncated;
		}
	}

	*resSize = dest;
	return mimeSuccess;
}